package com.sangcomz.fishbun.ui.picker;

import com.sangcomz.fishbun.BaseAbilitySlice;
import com.sangcomz.fishbun.FishBun;
import com.sangcomz.fishbun.Fishton;
import com.sangcomz.fishbun.ResourceTable;
import com.sangcomz.fishbun.adapter.image.ImageAdapter;
import com.sangcomz.fishbun.datasource.*;
import com.sangcomz.fishbun.permission.PermissionCheck;
import com.sangcomz.fishbun.ui.album.ui.slice.AlbumAbilitySlice;
import com.sangcomz.fishbun.ui.detail.ui.DetailImageAbility;
import com.sangcomz.fishbun.ui.picker.listener.OnPickerActionListener;
import com.sangcomz.fishbun.ui.picker.model.*;
import com.sangcomz.fishbun.util.*;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.DragInfo;
import ohos.agp.components.ListContainer;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.window.dialog.ToastDialog;
import ohos.agp.window.service.WindowManager;
import ohos.event.commonevent.*;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import ohos.multimodalinput.event.TouchEvent;
import ohos.rpc.RemoteException;
import ohos.utils.PacMap;
import ohos.utils.net.Uri;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.*;

public class PickerAbilitySlice extends BaseAbilitySlice implements PickerContract.View, OnPickerActionListener {

    private PickerContract.Presenter pickerPresenter;
    private ListContainer listView;
    private PickerProvider provider;
    private BaseGridSliceProvider.GridConfig gridConfig;
    private CommonToolbar toolbar;
    private EventSubscriber eventSubscriber;

    public void onSaveAbilityState(PacMap outState) {
        try {
            outState.putString(SAVE_INSTANCE_SAVED_IMAGE, cameraUtil.getSavedPath());
            outState.putSerializableObject(SAVE_INSTANCE_NEW_IMAGES, new ArrayList<>(pickerPresenter.getAddedImagePathList()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void onRestoreAbilityState(PacMap inState) {

        try {
            Optional<Serializable> pathList = inState.getSerializable(SAVE_INSTANCE_NEW_IMAGES);
            ArrayList<Uri> addedImagePathList = (ArrayList<Uri>) pathList.get();
            String savedImage = inState.getString(SAVE_INSTANCE_SAVED_IMAGE);
            if (addedImagePathList != null) {
                pickerPresenter.addAllAddedPath(addedImagePathList);
            }
            if (savedImage != null) {
                cameraUtil.setSavedPath(savedImage);
            }
            pickerPresenter.getPickerListItem();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);

        //订阅事件
        MatchingSkills skills = new MatchingSkills();
        skills.addEvent(PERMISSION_CALLBACK);
        CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(skills);

        eventSubscriber = new EventSubscriber(subscribeInfo);
        try {
            CommonEventManager.subscribeCommonEvent(eventSubscriber);
        } catch (RemoteException e) {
            e.printStackTrace();
        }

        setUIContent(ResourceTable.Layout_ability_photo_picker);
        initView();
        onCreateOptionsMenu();
        if (checkPermission()) pickerPresenter.getPickerListItem();
    }

    @Override
    protected void onBackPressed() {
        pickerPresenter.transImageFinish();
        super.onBackPressed();
    }

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
        super.onAbilityResult(requestCode, resultCode, resultData);
        switch (requestCode) {
            case TAKE_A_PICTURE_REQUEST_CODE:
                if (resultCode == RESULT_OK) {
                    pickerPresenter.onSuccessTakePicture();
                } else {
                    if (cameraUtil.getSavedPath() != null) {
                        new File(cameraUtil.getSavedPath()).delete();
                    }
                }
                break;
            case ENTER_DETAIL_REQUEST_CODE:
                if (resultCode == RESULT_OK) {
                    pickerPresenter.onDetailImageActivityResult();
                }
                break;
        }
    }

    public boolean onCreateOptionsMenu() {

        pickerPresenter.getPickerMenuViewData(new PickerContract.Presenter.PickerMenuViewDataCallback() {
            @Override
            public void callback(PickerMenuViewData pickerMenuViewData) {
                if (pickerMenuViewData.getDrawableDoneButton() != null) {
                    toolbar.hideAllSelectBtn();
                    toolbar.btnSelect.setVisibility(Component.VISIBLE);
                    toolbar.setImgSelect(pickerMenuViewData.getDrawableAllDoneButton());
                } else if (pickerMenuViewData.getStrDoneMenu() != null) {
                    toolbar.hideAllSelectBtn();
                    toolbar.btnSelectTitle.setTextColor(new Color(pickerMenuViewData.getColorTextMenu()));
                    toolbar.btnSelectTitle.setText(pickerMenuViewData.getStrDoneMenu());
                    toolbar.btnSelectTitle.setVisibility(Component.VISIBLE);
                }
                if (pickerMenuViewData.getUseAllDoneButton()) {
                    if (pickerMenuViewData.getDrawableAllDoneButton() != null) {
                        toolbar.setImgSelectAll(pickerMenuViewData.getDrawableAllDoneButton());
                    } else if (pickerMenuViewData.getStrAllDoneMenu() != null) {
                        toolbar.btnSelectAllTitle.setTextColor(new Color(pickerMenuViewData.getColorTextMenu()));
                        toolbar.btnSelectAllTitle.setText(pickerMenuViewData.getStrAllDoneMenu());
                        toolbar.btnSelectAllTitle.setVisibility(Component.VISIBLE);
                    }
                }
            }
        });

        return true;
    }

    private void onOptionsItemSelected(Component item) {
        item.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (item.getId() == ResourceTable.Id_btn_select || item.getId() == ResourceTable.Id_btn_select_title) {
                    pickerPresenter.onClickMenuDone();
                } else if (item.getId() == ResourceTable.Id_btn_select_all || item.getId() == ResourceTable.Id_btn_select_all_title) {
                    pickerPresenter.onClickMenuAllDone();
                } else if (item.getId() == ResourceTable.Id_btn_back) {
                    pickerPresenter.transImageFinish();
                }
            }
        });

    }

    private void initView() {

        gridConfig = new BaseGridSliceProvider.GridConfig();
        gridConfig.setPadding(1);
        gridConfig.setIndexCount(4);

        try {
            pickerPresenter = new PickerPresenter(this,
                    new PickerRepositoryImpl(new ImageDataSourceImpl(DataAbilityHelper.creator(this)),
                            new FishBunDataSourceImpl(Fishton.getInstance()),
                            new PickerIntentDataSourceImpl(getAbility().getIntent()),
                            new CameraDataSourceImpl(this)),
                    new MainUiHandler());
            pickerPresenter.getDesignViewData();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public void showImageList(List<PickerListItem> imageList, ImageAdapter adapter, Boolean hasCameraInPickerPage) {
        setImageList(imageList, adapter, hasCameraInPickerPage);
    }

    private void setImageList(List<PickerListItem> pickerList,
                              ImageAdapter imageAdapter,
                              boolean hasCameraInPickerPage) {
        if (provider == null) {
            provider = new PickerProvider(this, imageAdapter, this, gridConfig, hasCameraInPickerPage);
            listView.setItemProvider(provider);

        }
        provider.setPickerList(pickerList);
    }

    @Override
    public void takePicture(String saveDir) {
        cameraUtil.takePicture(this, saveDir, TAKE_A_PICTURE_REQUEST_CODE);
    }

    @Override
    public void setToolbarTitle(PickerViewData pickerViewData, int selectedCount, String albumName) {

        if (pickerViewData.getMaxCount() == 1 || !pickerViewData.isShowCount()) {
            toolbar.tvTitle.setText(albumName);
        } else {
            String title = getString(ResourceTable.String_title_toolbar, albumName, selectedCount, pickerViewData.getMaxCount());
            toolbar.tvTitle.setText(title);
        }
    }

    @Override
    public void initToolBar(PickerViewData pickerViewData) {

        toolbar = (CommonToolbar) findComponentById(ResourceTable.Id_list_picker_toolbar);

//        ShapeElement background = new ShapeElement();
//        background.setRgbColor(new RgbColor(pickerViewData.getColorActionBar()));
        toolbar.setBackgroundColor(pickerViewData.getColorActionBar());
        toolbar.tvTitle.setTextColor(new Color(pickerViewData.getColorActionBarTitle()));
        WindowManager.getInstance().getTopWindow().get().setStatusBarColor(pickerViewData.getColorStatusBar());

        toolbar.btnBack.setVisibility(Component.VISIBLE);
        toolbar.btnSelect.setVisibility(Component.VISIBLE);

        if (pickerViewData.getDrawableHomeAsUpIndicator() != null) {
            toolbar.setImgBack(pickerViewData.getDrawableHomeAsUpIndicator());
        }

        onOptionsItemSelected(toolbar.btnBack);
        onOptionsItemSelected(toolbar.btnSelect);
        onOptionsItemSelected(toolbar.btnSelectAll);
        onOptionsItemSelected(toolbar.btnSelectAllTitle);
        onOptionsItemSelected(toolbar.btnSelectTitle);
    }

    @Override
    public void initRecyclerView(PickerViewData pickerViewData) {
        listView = (ListContainer) findComponentById(ResourceTable.Id_list_picker_list);
    }

    @Override
    public void showLimitReachedMessage(String messageLimitReached) {

//        new ToastDialog(getContext())
//                .setText(messageLimitReached)
//                .setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT)
//                .show();
        ToastUtil.showToast(getContext(), messageLimitReached);
    }

    @Override
    public void showMinimumImageMessage(int currentSelectedCount) {

        String msg = getString(ResourceTable.String_msg_minimum_image, currentSelectedCount);
//        new ToastDialog(getContext())
//                .setText(msg)
//                .setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT)
//                .show();
        ToastUtil.showToast(getContext(), msg);
    }

    @Override
    public void showNothingSelectedMessage(String messageNotingSelected) {
//        new ToastDialog(getContext())
//                .setText(messageNotingSelected)
//                .setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT)
//                .show();
        ToastUtil.showToast(getContext(), messageNotingSelected);
    }

    @Override
    public void onCheckStateChange(int position, PickerListItem.Image image) {
        if (provider != null) {
            provider.updatePickerListItem(position, image);
        }
    }

    public void onCheckStateChange(PickerRepository pickerRepository) {
        if (provider != null) {
            provider.updatePickerListItem(pickerRepository);
        }
    }

    @Override
    public void showDetailView(int position) {
        startAbilityForResult(DetailImageAbility.getDetailImageActivity(position), ENTER_DETAIL_REQUEST_CODE);
    }

    @Override
    public void finishActivity() {
        Intent intent = new Intent();
        getAbility().setResult(RESULT_OK, intent);
        terminateAbility();
    }

    @Override
    public void finishActivityWithResult(List<Uri> selectedImages) {
        Intent intent = new Intent();
        getAbility().setResult(RESULT_OK, intent);
        intent.setSequenceableArrayListParam(FishBun.INTENT_PATH, new ArrayList<>(selectedImages));
        terminateAbility();
    }

    @Override
    public void takeANewPictureWithFinish(int position, List<Uri> addedImageList) {
        getAbility().setResult(TAKE_A_NEW_PICTURE_RESULT_CODE, new Intent());
        terminateAbility();
    }

    @Override
    public void addImage(PickerListItem.Image pickerListImage) {
        if (provider != null) {
            provider.addImage(pickerListImage);
        }
    }

    @Override
    public void onSuccessTakePicture() {
        if (cameraUtil.getSavedPath() == null) {
            return;
        }
        String savedPath = cameraUtil.getSavedPath();
        File savedFile = new File(savedPath);

        new SingleMediaScanner(this, savedFile, new SingleMediaScanner.SingleMediaScannerCallback() {
            @Override
            public void onScanCompleted() {
                pickerPresenter.successTakePicture(Uri.getUriFromFile(savedFile));
            }
        });
    }

    @Override
    public void takePicture() {

        if (checkCameraPermission()) {
            pickerPresenter.takePicture();
        }
    }

    @Override
    public void onDeselect() {
        pickerPresenter.getPickerListItem();
    }

    @Override
    public void onClickImage(int position) {
        pickerPresenter.onClickImage(position);
    }

    @Override
    public void onClickThumbCount(int position) {
        pickerPresenter.onClickThumbCount(position);
    }

    private boolean checkPermission() {
        return permissionCheck.checkStoragePermission(PERMISSION_STORAGE);
    }

    private boolean checkCameraPermission() {
        return permissionCheck.checkCameraPermission(PERMISSION_CAMERA);
    }

    class EventSubscriber extends CommonEventSubscriber {

        public EventSubscriber(CommonEventSubscribeInfo info) {
            super(info);
        }

        @Override
        public void onReceiveEvent(CommonEventData commonEventData) {
            Intent intent = commonEventData.getIntent();

            if (intent.getAction().equals(PERMISSION_CALLBACK)) {

                int requestCode = intent.getIntParam(REQUEST_CODE, -1);
                int[] grantResults = intent.getIntArrayParam(GRANT_RESULTS);

                switch (requestCode) {
                    case BaseAbilitySlice.PERMISSION_STORAGE:
                        if (grantResults[0] == 0) {
                            pickerPresenter.getPickerListItem();
                        }
                        break;
                    case BaseAbilitySlice.PERMISSION_CAMERA:
                        if (grantResults != null && grantResults.length > 0) {
                            if (grantResults[0] == 0) {
                                pickerPresenter.takePicture();
                            }
                        } else {
                            new PermissionCheck(getContext()).showPermissionDialog();
                        }
                        break;
                }
            } else if (intent.getAction().equals(ON_SAVE_ABILITY_STATE)) {

                PacMap outState = intent.getSerializableParam(OUT_STATE);
                onSaveAbilityState(outState);

            } else if (intent.getAction().equals(ON_RESTORE_ABILITY_STATE)) {

                PacMap inState = intent.getSerializableParam(IN_STATE);
                onRestoreAbilityState(inState);

            }
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        try {
            CommonEventManager.unsubscribeCommonEvent(eventSubscriber);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}
